home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / lha_axeman / crcio.c < prev    next >
C/C++ Source or Header  |  1995-09-01  |  6KB  |  333 lines

  1. /***********************************************************
  2.     crcio.c -- input/output
  3. ***********************************************************/
  4. #ifdef __STDC__
  5. #include <stdlib.h>
  6. #include <stdarg.h>
  7. #endif
  8.  
  9. #include <errno.h>
  10. #include "slidehuf.h"
  11. #include "intrface.h"
  12.  
  13. extern int text_mode;
  14. extern int prev_char;
  15. extern int verify_mode;
  16. #ifdef EUC
  17. extern int euc_mode;
  18. extern int generic_format;
  19. #endif
  20.  
  21. long reading_size;
  22.  
  23. #define CRCPOLY  0xA001  /* CRC-16 */
  24. #define UPDATE_CRC(c) crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT)
  25.  
  26. FILE *infile, *outfile;
  27. unsigned short crc, bitbuf;
  28.  
  29. static unsigned short crctable[UCHAR_MAX + 1];
  30. static unsigned char  subbitbuf, bitcount;
  31. #ifdef EUC
  32. static int putc_euc_cache;
  33. #endif
  34. static int getc_euc_cache;
  35.  
  36. void make_crctable(void)
  37. {
  38.     unsigned int i, j, r;
  39.  
  40.     for (i = 0; i <= UCHAR_MAX; i++)
  41.   {
  42.         r = i;
  43.         for(j = 0; j < CHAR_BIT; j++)
  44.             if(r & 1)
  45.         r = (r >> 1) ^ CRCPOLY;
  46.             else       r >>= 1;
  47.             crctable[i] = r;
  48.     }
  49. }
  50.  
  51.  
  52. extern int quiet;
  53. extern int indicator_count;
  54. extern int indicator_threshold;
  55.  
  56. static void put_indicator(LONG count)
  57. {
  58.     if(!quiet && indicator_threshold)
  59.     {
  60.         while( count > indicator_count)
  61.     {
  62.             putchar ('o');
  63.             fflush (stdout);
  64.             indicator_count += indicator_threshold;
  65.         }
  66.     }
  67. }
  68.  
  69. unsigned short calccrc(UBYTE *p , int n)
  70. {
  71.     reading_size += n;
  72.     put_indicator( reading_size );
  73.     while (n-- > 0) UPDATE_CRC(*p++);
  74.     return crc;
  75. }
  76.  
  77. void fillbuf(UBYTE n)  /* Shift bitbuf n bits left, read n bits */
  78. {
  79.   while (n > bitcount)
  80.   {
  81.     n -= bitcount;
  82.     bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
  83.     if(compsize != 0)
  84.     {
  85.       compsize--;  subbitbuf = (unsigned char) getc(infile);
  86.     } else subbitbuf = 0;
  87.     bitcount = CHAR_BIT;
  88.   }
  89.   bitcount -= n;
  90.   bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
  91.   subbitbuf <<= n;
  92. }
  93.  
  94. unsigned short getbits(UBYTE n)
  95. {
  96.     unsigned short x;
  97.  
  98.     x = bitbuf >> (2 * CHAR_BIT - n);  fillbuf(n);
  99.     return x;
  100. }
  101.  
  102. void putcode(UBYTE n , SHORT x)  /* Write rightmost n bits of x */
  103. {
  104.   while (n >= bitcount) {
  105.     n -= bitcount;
  106.     subbitbuf += x >> (USHRT_BIT - bitcount);
  107.     x <<= bitcount;
  108.     if (compsize < origsize) {
  109.       if (fwrite(&subbitbuf, 1, 1, outfile) == 0)
  110.     exit( errno );
  111.       compsize++;
  112.     } else unpackable = 1;
  113.     subbitbuf = 0;  bitcount = CHAR_BIT;
  114.   }
  115.   subbitbuf += x >> (USHRT_BIT - bitcount);
  116.   bitcount -= n;
  117. }
  118.  
  119. void putbits( n , x )  /* Write rightmost n bits of x */
  120. unsigned char n;
  121. unsigned short x;
  122. {
  123.     x <<= USHRT_BIT - n;
  124.     while (n >= bitcount) {
  125.         n -= bitcount;
  126.         subbitbuf += x >> (USHRT_BIT - bitcount);
  127.         x <<= bitcount;
  128.         if (compsize < origsize) {
  129.             if (fwrite(&subbitbuf, 1, 1, outfile) == 0)
  130.                 /* fileerror(WTERR, outfile); */
  131.                 exit( errno );
  132.             compsize++;
  133.         } else unpackable = 1;
  134.         subbitbuf = 0;  bitcount = CHAR_BIT;
  135.     }
  136.     subbitbuf += x >> (USHRT_BIT - bitcount);
  137.     bitcount -= n;
  138. }
  139.  
  140. int fread_crc( p, n, fp )
  141. unsigned char *p;
  142. int n;
  143. FILE *fp;
  144. {
  145.     if ( text_mode )
  146.       n = fread_txt(p, n, fp);
  147.     else
  148.       n = fread(p, 1, n, fp);
  149.     calccrc(p, n);
  150.     return n;
  151. }
  152.  
  153. void fwrite_crc( p, n, fp )
  154. unsigned char *p;
  155. int n;
  156. FILE *fp;
  157. {
  158.   calccrc(p,n);
  159.   if ( verify_mode ) return;
  160.  
  161.   if ( fp )
  162.     {
  163.       if ( text_mode )
  164.     {
  165.       if ( fwrite_txt(p , n , fp) )
  166.         fatal_error("File write error\n");
  167.     }
  168.       else
  169.     {
  170.       if (fwrite(p, 1, n, fp) < n)
  171.         fatal_error("File write error\n");
  172.     }
  173.     }
  174. }
  175.  
  176. void init_code_cache(void)    /* called from copyfile() in util.c */
  177. {
  178. #ifdef EUC
  179.     putc_euc_cache = EOF;
  180. #endif
  181.     getc_euc_cache = EOF;
  182. }
  183.  
  184. void init_getbits(void)
  185. {
  186.     bitbuf = 0;  subbitbuf = 0;  bitcount = 0;
  187.     fillbuf(2 * CHAR_BIT);
  188. #ifdef EUC
  189.     putc_euc_cache = EOF;
  190. #endif
  191. }
  192.  
  193. void init_putbits(void)
  194. {
  195.     bitcount = CHAR_BIT;  subbitbuf = 0;
  196.     getc_euc_cache = EOF;
  197. }
  198.  
  199. #ifdef EUC
  200. void
  201. putc_euc(c, fd)
  202. int c;
  203. FILE *fd;
  204. {
  205.   int d;
  206.  
  207.   if (putc_euc_cache == EOF)
  208.     {
  209.       if (!euc_mode || c < 0x81 || c > 0xFC)
  210.         {
  211.           putc(c, fd);
  212.           return;
  213.         }
  214.       if (c >= 0xA0 && c < 0xE0)
  215.         {
  216.           putc(0x8E, fd);      /* single shift */
  217.           putc(c, fd);
  218.           return;
  219.         }
  220.       putc_euc_cache = c;      /* save first byte */
  221.       return;
  222.     }
  223.   d = putc_euc_cache;
  224.   putc_euc_cache = EOF;
  225.   if (d >= 0xA0)
  226.     d -= 0xE0 - 0xA0;
  227.   if (c > 0x9E)
  228.     {
  229.       c = c - 0x9F + 0x21;
  230.       d = (d - 0x81) * 2 + 0x22;
  231.     }
  232.   else
  233.     {
  234.       if (c > 0x7E)
  235.         c --;
  236.       c -= 0x1F;
  237.       d = (d - 0x81) * 2 + 0x21;
  238.     }
  239.   putc(0x80 | d, fd);
  240.   putc(0x80 | c, fd);
  241. }
  242. #endif
  243.  
  244. int
  245. fwrite_txt( p , n , fp )
  246. unsigned char *p;
  247. int n;
  248. FILE *fp;
  249. {
  250.   while ( --n>=0 )
  251.     {
  252.       if ( *p!='\015' && *p!='\032' )
  253.     {
  254. #ifdef EUC
  255.       putc_euc( *p , fp );
  256. #else
  257.       putc( *p , fp );
  258. #endif
  259.     }
  260.  
  261.       prev_char = *p++;
  262.     }
  263.   return ( ferror( fp ) );
  264. }
  265.  
  266. int
  267. fread_txt( p , n , fp )
  268. unsigned char *p;
  269. int n;
  270. FILE *fp;
  271. {
  272.   int c;
  273.   int cnt = 0;
  274.  
  275.   while (cnt < n)
  276.     {
  277.       if (getc_euc_cache != EOF)
  278.         {
  279.           c = getc_euc_cache;
  280.           getc_euc_cache = EOF;
  281.         }
  282.       else
  283.         {
  284.           if ((c = fgetc(fp)) == EOF)
  285.             break;
  286.           if (c == '\n') {
  287.             getc_euc_cache = c;
  288.             c = '\r';
  289.       }
  290. #ifdef EUC
  291.       else if (euc_mode && (c == 0x8E || 0xA0 < c && c < 0xFF))
  292.         {
  293.           int d = fgetc(fp);
  294.           if (d == EOF)
  295.             {
  296.           *p++ = c;
  297.               cnt ++;
  298.               break;
  299.             }
  300.           if (c == 0x8E)    /* single shift (KANA) */
  301.             {
  302.           if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
  303.             c = d | 0x80;
  304.           else
  305.             getc_euc_cache = d;
  306.             }
  307.           else
  308.               {
  309.                 if (0xA0 < d && d < 0xFF)    /* if GR */
  310.                   {
  311.                     c &= 0x7F;    /* convert to MS-kanji */
  312.                     d &= 0x7F;
  313.                     if (!(c & 1))
  314.                       {
  315.                         c --;
  316.                         d += 0x7F - 0x21;
  317.                       }
  318.               if ((d += 0x40 - 0x21) > 0x7E)
  319.             d ++;
  320.               if ((c = (c >> 1) + 0x71) >= 0xA0)
  321.                 c += 0xE0 - 0xA0;
  322.                   }
  323.           getc_euc_cache = d;
  324.               }
  325.         }
  326. #endif
  327.         }
  328.       *p++ = c;
  329.       cnt ++;
  330.     }
  331.   return cnt;
  332. }
  333.